﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Domain.MainModule.Entities;
using Infraestructure.Data.MainModule.UnitOfWork;
using Infraestructure.CrossCutting.Logging;
using Domain.MainModule.Countries;
using Infraestructure.Data.MainModule.Repositories;

namespace Infraestructure.Data.MainModule.Tests.RepositoriesTests
{
    [TestClass()]
    public class CountryRepositoryTests
        : RepositoryTestsBase<Country>
    {

        IMainModuleUnitOfWork context;
        ITraceManager traceManager;
        ICountryRepository repository;

        public CountryRepositoryTests()
        {
            context = GetUnitOfWork();
            traceManager = this.GetTraceManager();
            repository = new CountryRepository(context, traceManager);
        }

        public override System.Linq.Expressions.Expression<Func<Country, bool>> FilterExpression
        {
            get { return c => c.CountryId == TestConstants.Instance.COUNTRY_ID; }
        }

        public override System.Linq.Expressions.Expression<Func<Country, Guid>> OrderByExpression
        {
            get { return c => c.CountryId; }
        }

        [TestMethod()]
        [ExpectedException(typeof(ArgumentNullException))]
        public void FindCountry_Invoke_NullSpecThrowNewArgumentNullException_Test()
        {
            //Arrange 
            IMainModuleUnitOfWork context = GetUnitOfWork();
            ITraceManager traceManager = this.GetTraceManager();
            CountryRepository repository = new CountryRepository(context, traceManager);

            //Act
            repository.FindCountry(null);
        }

        #region CountryIdSpecification

        [TestMethod()]
        public void FindCountry_Invoke_InvalidIdReturnNullObject_Test()
        {
            //Arrange 
            IMainModuleUnitOfWork context = GetUnitOfWork();
            ITraceManager traceManager = this.GetTraceManager();
            CountryRepository repository = new CountryRepository(context, traceManager);

            Guid invalidId = new Guid("11111111-1111-1111-1111-111111111111");
            CountryIdSpecification spec = new CountryIdSpecification(invalidId);

            //Act
            Country country = repository.FindCountry(spec);

            //Assert
            Assert.IsNull(country);
        }

        [TestMethod()]
        public void FindCountryByCountryId_Invoke_Test()
        {
            //Arrange 
            IMainModuleUnitOfWork context = GetUnitOfWork();
            ITraceManager traceManager = this.GetTraceManager();
            ICountryRepository repository = new CountryRepository(context, traceManager);

            CountryIdSpecification spec = new CountryIdSpecification(TestConstants.Instance.COUNTRY_ID);

            //Act
            Country country = repository.FindCountry(spec);

            //Assert
            Assert.IsNotNull(country);
        }

        #endregion

        #region CountryISOAlpha2Specification

        [TestMethod()]
        public void FindCountry_Invoke_InvalidISOAlpha2ReturnNullObject_Test()
        {
            //Arrange 
            IMainModuleUnitOfWork context = GetUnitOfWork();
            ITraceManager traceManager = this.GetTraceManager();
            ICountryRepository repository = new CountryRepository(context, traceManager);

            string invalidISOALpha2 = "XX";
            CountryISOAlpha2Specification spec = new CountryISOAlpha2Specification(invalidISOALpha2);

            //Act
            Country country = repository.FindCountry(spec);

            //Assert
            Assert.IsNull(country);
        }

        [TestMethod()]
        public void FindCountryByISOAlpha2_Invoke_Test()
        {
            //Arrange 
            IMainModuleUnitOfWork context = GetUnitOfWork();
            ITraceManager traceManager = this.GetTraceManager();
            ICountryRepository repository = new CountryRepository(context, traceManager);

            CountryISOAlpha2Specification spec = new CountryISOAlpha2Specification(TestConstants.Instance.ISOALPHA2);

            //Act
            Country country = repository.FindCountry(spec);

            //Assert
            Assert.IsNotNull(country);
        }

        #endregion

        #region CountryISOAlpha3Specification

        [TestMethod()]
        public void FindCountry_Invoke_InvalidISOAlpha3ReturnNullObject_Test()
        {
            //Arrange 
            IMainModuleUnitOfWork context = GetUnitOfWork();
            ITraceManager traceManager = this.GetTraceManager();
            ICountryRepository repository = new CountryRepository(context, traceManager);

            string invalidISOAlpha3 = "XX";
            CountryISOAlpha3Specification spec = new CountryISOAlpha3Specification(invalidISOAlpha3);

            //Act
            Country country = repository.FindCountry(spec);

            //Assert
            Assert.IsNull(country);
        }

        [TestMethod()]
        public void FindCountryByISOAlpha3_Invoke_Test()
        {
            //Arrange 
            IMainModuleUnitOfWork context = GetUnitOfWork();
            ITraceManager traceManager = this.GetTraceManager();
            ICountryRepository repository = new CountryRepository(context, traceManager);

            CountryISOAlpha3Specification spec = new CountryISOAlpha3Specification(TestConstants.Instance.ISOALPHA3);

            //Act
            Country country = repository.FindCountry(spec);

            //Assert
            Assert.IsNotNull(country);
        }

        #endregion

        #region CountryISONumericSpecification

        [TestMethod()]
        public void FindCountry_Invoke_InvalidISONumericReturnNullObject_Test()
        {
            //Arrange 
            IMainModuleUnitOfWork context = GetUnitOfWork();
            ITraceManager traceManager = this.GetTraceManager();
            ICountryRepository repository = new CountryRepository(context, traceManager);

            string invalidISONumeric = "XX";
            CountryISONumericSpecification spec = new CountryISONumericSpecification(invalidISONumeric);

            //Act
            Country country = repository.FindCountry(spec);

            //Assert
            Assert.IsNull(country);
        }

        [TestMethod()]
        public void FindCountryByISONumeric_Invoke_Test()
        {
            //Arrange 
            IMainModuleUnitOfWork context = GetUnitOfWork();
            ITraceManager traceManager = this.GetTraceManager();
            ICountryRepository repository = new CountryRepository(context, traceManager);

            CountryISONumericSpecification spec = new CountryISONumericSpecification(TestConstants.Instance.ISONUMERIC);

            //Act
            Country country = repository.FindCountry(spec);

            //Assert
            Assert.IsNotNull(country);
        }

        #endregion

        #region CountryNameSpecification

        [TestMethod()]
        public void FindCountry_Invoke_InvalidCountryNameReturnNullObject_Test()
        {
            //Arrange 
            IMainModuleUnitOfWork context = GetUnitOfWork();
            ITraceManager traceManager = this.GetTraceManager();
            ICountryRepository repository = new CountryRepository(context, traceManager);

            string invalidCountryName = "Felicidonia";
            CountryNameSpecification spec = new CountryNameSpecification(invalidCountryName);

            //Act
            Country country = repository.FindCountry(spec);

            //Assert
            Assert.IsNull(country);
        }

        [TestMethod()]
        public void FindCountryByCountryName_Invoke_Test()
        {
            //Arrange 
            IMainModuleUnitOfWork context = GetUnitOfWork();
            ITraceManager traceManager = this.GetTraceManager();
            ICountryRepository repository = new CountryRepository(context, traceManager);

            CountryNameSpecification spec = new CountryNameSpecification(TestConstants.Instance.COUNTRY_NAME);

            //Act
            Country country = repository.FindCountry(spec);

            //Assert
            Assert.IsNotNull(country);
        }

        #endregion
    }
}
